package tt.dz.biz.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.util.Assert;
import tt.dz.biz.service.Job.JobLockService;
import tt.dz.common.AppContxtUtil;
import tt.dz.common.DzConstants;
import tt.dz.common.DzConstants.jobStatus;
import tt.dz.common.LogUtil;
import tt.dz.vo.JobLockVO;

public abstract class AbstractJob
  extends QuartzJobBean
{
  protected String jobCode;
  protected JobLockVO jobvo;
  protected JobLockService jobLockService;
  
  public JobLockVO getJobvo()
  {
    return this.jobvo;
  }
  
  public void setJobvo(JobLockVO jobvo)
  {
    this.jobvo = jobvo;
  }
  
  public JobLockService getJobLockService()
  {
    return this.jobLockService;
  }
  
  public void setJobLockService(JobLockService jobLockService)
  {
    this.jobLockService = jobLockService;
  }
  
  public void setJobCode(String jobCode)
  {
    this.jobCode = jobCode;
  }
  
  protected final void executeInternal(JobExecutionContext context)
    throws JobExecutionException
  {
    try
    {
      this.jobCode = getJobCode();
      LogUtil.debug("记账job start");
      boolean beforeOk = beforeExecute();
      if (beforeOk)
      {
        executeJob(context);
        afterExecute();
      }
    }
    catch (Exception e)
    {
      afterExecute();
      LogUtil.error("job异常", e);
      throw new JobExecutionException(e);
    }
  }
  
  protected boolean beforeExecute()
    throws JobExecutionException
  {
    try
    {
      Assert.notNull(this.jobCode, "jobCode参数是必须设置，请检查 getJobCode方法");
      this.jobLockService = ((JobLockService)AppContxtUtil.getBean("jobLockService"));
      Assert.notNull(this.jobLockService, "从容器中获取jobLockService异常，请联系管理员。");
      this.jobvo = this.jobLockService.updateJobStatusForLock(this.jobCode);
      return this.jobvo != null;
    }
    catch (Exception e)
    {
      LogUtil.error(e.getMessage(), e);
      throw new JobExecutionException(e);
    }
  }
  
  protected abstract void executeJob(JobExecutionContext paramJobExecutionContext)
    throws JobExecutionException;
  
  protected void afterExecute()
  {
    if (this.jobvo != null)
    {
      this.jobvo.setStatus(DzConstants.jobStatus.WAITING.value());
      this.jobLockService.updateJobStatusForRestart(this.jobvo);
      try
      {
        this.jobLockService.updateLastRunTimeByCode(this.jobvo.getJobCode());
      }
      catch (Exception e)
      {
        LogUtil.error("设置job运行时间异常，jobcode为：" + this.jobvo.getJobCode(), e);
      }
    }
  }
  
  protected abstract String getJobCode();
}
